﻿
namespace EasyStep.Business.Managers.FileSystem
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using EasyStep.Business.Interfaces.Managers;
    using EasyStep.Data.Entities;
    using EasyStep.Business.Interfaces;


    public class TestStepManager : ITestStepManager
    {
        private ITestDataContext Context { get; set; }

        public TestStepManager(ITestDataContext context)
        {
            Context = context;
        }

        public IEnumerable<TestStep> GetTestSteps(Guid forTest)
        {
            throw new NotImplementedException();
        }

        public TestStep Create(TestStep data)
        {
            throw new NotImplementedException();
        }

        public TestStep Update(TestStep data)
        {
            throw new NotImplementedException();
        }

        public TestStep Delete(TestStep data)
        {
            throw new NotImplementedException();
        }


        public string Convert(TestStep item)
        {
            var sb = new StringBuilder();
            if (!Guid.Empty.Equals(item.Action.ParentId))
            {
                item.Action.Parent = Context.ActionManager.Get(item.Action.ParentId);
                sb.AppendFormat("{0}, {1} = ", item.Action.Parent.Name, item.Action.Name);
            }
            else if (item.Action.IsAbstract)
            {
                sb.AppendFormat("{0}, ", item.Action.Name);
            }
            else
                sb.AppendFormat("{0} = ", item.Action.Name);

            if (item.Action.RequireLocator && item.Locator != null)
                sb.AppendFormat("{0}, ", EncodeParam(item.Locator.Value));
            if (item.Action.RequireData && item.Data != null)
                sb.AppendFormat("{0}, ", EncodeParam(item.Data.Value));
            var result = sb.ToString();
            result = result.EndsWith(", ")
                ? result.TrimEnd(new char[] { ' ', ',' })
                : result;
            return result;
        }


        public TestStep Convert(string serializedItem)
        {
            if (string.IsNullOrEmpty(serializedItem)) return null;
            var i = serializedItem.IndexOf("=");
            if (i < 0)
            {
                serializedItem = serializedItem + "=";
                i = serializedItem.IndexOf("=");
            }
            //read action info
            var ss = serializedItem.Substring(0, i).Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
            var action = ss.Length == 0 ? null : Context.ActionManager.GetByName((ss[0] ?? "").Trim());
            var parent = ss.Length > 1 ? action : null;
            if (ss.Length > 1 && parent != null)
            {
                action = Context.ActionManager
                    .GetChildren(parent.Id)
                    .Where(a => a.Name.Equals((ss[1] ?? "").Trim(), StringComparison.OrdinalIgnoreCase))
                    .FirstOrDefault();
            }
            if (action == null) return null;
            action.Parent = parent;
            //read locator and data
            var exParams = serializedItem.Substring(i + 1);
            TestData locator = null;
            TestData data = null;
            if (action.RequireLocator)
                exParams = ParceTestData(exParams, out locator);
            if (action.RequireData)
                exParams = ParceTestData(exParams, out data);
            return new TestStep()
            {
                Id = Guid.NewGuid(),
                Action = action,
                RequiersScreenShot = action.RequireScreenShot,
                ActionId = action == null ? Guid.Empty : action.Id,
                Locator = locator,
                Data = data
            };

        }
        private string EncodeParam(string stringToEncode)
        {
            if ((stringToEncode ?? "").Contains(","))
                return string.Concat("'", stringToEncode.Replace("'", "''"), "'");
            else
                return stringToEncode;
        }

        private string ParceTestData(string comaseparatedText, out TestData parcedData)
        {
             parcedData = null;
            if (string.IsNullOrEmpty(comaseparatedText)) return comaseparatedText;
            string rightPart = null;
            string leftPart = null;
            comaseparatedText = comaseparatedText.Trim();
            if (comaseparatedText.StartsWith("'"))
            {
                var rb = new StringBuilder();
                var sb = new StringBuilder(comaseparatedText);
                while (sb.Length > 1)
                {
                    sb.Remove(0, 1);
                    if (sb[0] != '\'')
                        rb.Append(sb[0]);
                    else if (sb.Length > 1 && sb[1] == '\'')
                    {
                        rb.Append(sb[0]);
                        sb.Remove(0, 1);
                    }
                    else
                    {
                        rightPart = sb.Remove(0,1).ToString().Trim();
                        rightPart = !rightPart.StartsWith(",") ? rightPart : rightPart.Remove(0, 1);
                        break;
                    }
                }
                leftPart = rb.ToString();
            }
            else
            {
                var k = comaseparatedText.IndexOf(",");
                rightPart = k < 0 ? null : comaseparatedText.Substring(k + 1);
                leftPart = k < 0 ? comaseparatedText : comaseparatedText.Substring(0, k);
            }
            if ((leftPart ?? "").Trim() != "")
            {
                parcedData = new TestData() { Value = leftPart };
            }
            return rightPart;
        }
    }
}
